home *** CD-ROM | disk | FTP | other *** search
- /* #define rasterAndTime uncomment this line if you use raster files */
-
- /******************************************************************************/
- /* */
- /* I N T E R N A T I O N A L D A T A E N C R Y P T I O N A L G O R I T H M */
- /* */
- /******************************************************************************/
- /* Author: Richard De Moliner (demoliner@isi.ethz.ch) */
- /* Signal and Information Processing Laboratory */
- /* Swiss Federal Institute of Technology */
- /* CH-8092 Zuerich, Switzerland */
- /* Last Edition: 23 April 1992 */
- /* System: SUN SPARCstation, SUN cc C-Compiler, SUN-OS 4.1.1 */
- /******************************************************************************\
- NAME
- idea - encrypt and decrypt using IDEA
-
- SYNOPSIS
- idea [ -e | -d ] [ -r ] [ -ecb | -cbcN | -cfbN | -ofbN ]
- ( -k keyString | -K keyHexString )
- [ inputFile [ ouputFile ] ]
-
- idea [ -h | -H ] [ -tan | -abr ]
- [ -k keyString | -K keyHexString ]
- [ inputFile [ [ ouputFile ] hashvalFile ]
-
- DESCRIPTION
- Idea reads inputFile and writes the en/decrypted data to
- outputFile or writes the hash value to hashvalFile. If file
- name is not given in command line, idea uses standard input
- or output. If the input file name is given as '-', idea
- reads from the standard input.
-
- IDEA (International Data Encryption Algorithm) is a block
- cipher developed by Xuejia Lai and Prof. Dr. J. L. Massey at
- the Swiss Federal Institute of Technology.
-
- OPTIONS
- -e Encrypt data. (default)
-
- -d Decrypt data.
-
- -r InputFile is a raster-file.
-
- -k Key is specified with keyString.
-
- -K Key and initial values are specified with keyHexString.
-
- -h Compute a 128 bit hash value from the input data. The
- hash value is written to hashvalFile (or standard out-
- put).
-
- -H Compute a 128 bit hash value from the input data. The
- input is copied to outputFile (or standard output) and
- the hash value is written to hashvalFile (or standard
- error).
-
- Notation:
- N = interleave factor (1 is default)
- z = 128 bit key
- x[i] = 64 bit plaintext block
- y[i] = 64 bit ciphertext block
- x[1]..x[L] = plaintext (last block is filled with
- zeros)
- x[L+1] = length of plaintext in bits
- y[1]..y[L+1]= ciphertext
- IDEA(z, .) = encryption function
- IIDEA(z, .) = decryption function
- x = IIDEA(z, IDEA(z ,x))
-
- Encryption / Decrypion Modes:
-
- -ecb electronic code book mode
- y[i] = IDEA(z, x[i])
- x[i] = IIDEA(z, y[i])
-
- -cbc cipher block chaining mode (cbc1 is default)
- y[i] = IDEA(z, x[i] ^ y[i-N])
- x[i] = IIDEA(z, y[i]) ^ y[i-N]
-
- -cfb ciphertext feedback mode
- y[i] = x[i] ^ IDEA(z, y[i-N])
- x[i] = y[i] ^ IDEA(z, y[i-N])
-
- -ofb output feedback mode
- h[i] = IDEA(z, h[i-N])
- y[i] = x[i] ^ h[i]
- x[i] = y[i] ^ h[i]
-
- Hash Functions:
- If no key is given, idea uses the all zero key.
- hash value = h[L+1] * 2**64 + g[L+1]
- h[0] = z / 2**64
- g[0] = z % 2**64
-
- -tan tandem DM-scheme (default)
- w = IDEA(g[i-1] * 2**64 + x[i], h[i-1])
- h[i] = h[i-1] ^ w
- g[i] = g[i-1] ^ IDEA(x[i] * 2**64 + w, g[i-1])
-
- -abr abreast DM-scheme
- h[i] = h[i-1] ^ IDEA(g[i-1] * 2**64 + x[i], h[i-1])
- g[i] = g[i-1] ^ IDEA(x[i] * 2**64 + h[i-1], ~ g[i-1])
-
- Key Formats:
- keyHexString = { '0'..'9' | 'a'..'f' | 'A'..'F' | ':' }
- keyHexString = z:y[1-N]:y[2-N]:y[3-N]..
- keyString = { '!'..'~' } = z
-
- EXAMPLES
- To encrypt and decrypt a file in cipher block chaining mode
- with an interleave factor of 8:
-
- idea -e -cbc8 -K 12345:67:89::ab:cDEf data data.cr
- idea -d -cbc8 -K 12345:67:89::ab:cDef data.cr data.ori
- data and data.ori are identical
-
- To compute the hash value with tandem DM-scheme:
-
- idea -h data
-
- To compute the hash value and encrypt the data in one step:
-
- idea -Hk "k e y" data | idea -K 123:9a::eF - data.cr
-
- PATENT
- IDEA is registered as the international patent WO 91/18459
- "Device for Converting a Digital Block and the Use thereof".
- For commercial use of IDEA, one should contact
-
- ASCOM TECH AG
- Freiburgstrasse 370
- CH-3018 Bern, Switzerland
-
- AUTHOR
- Richard De Moliner (demoliner@isi.ethz.ch)
- Signal and Information Processing Laboratory
- Swiss Federal Institute of Technology
- CH-8092 Zurich, Switzerland
-
- BUGS
- This program is at most as strong as IDEA itself. So, we
- urge the user to use this program only after he has assured
- himself that IDEA is strong enough AND he has read the
- source code of this program and its libraries AND he has
- compiled the program himself with a troyan-free compiler. WE
- DO NOT GUARANTEE THAT THIS PROGRAM IS A DECENT ENCRYPTION
- PROGRAM.
-
- \******************************************************************************/
-
- #ifdef rasterAndTime
- #include <sys/times.h>
- #include <pixrect/pixrect_hs.h>
- #endif
-
- #include <stdio.h>
- #include <string.h>
- #include <crypt.h>
-
- #define TRUE 1 /* boolean constant for true */
- #define FALSE 0 /* boolean constant for false */
- #define nofTestData 163840 /* number of blocks encrypted in time test */
-
- #define nomode 0 /* no mode is specified */
- #define ecb 1 /* electronic code book mode */
- #define cbc 2 /* cipher block chaining mode */
- #define cfb 3 /* ciphertext feedback mode */
- #define ofb 4 /* output feedback mode */
- #define tan 5 /* tandem DM-scheme for hashing */
- #define abr 6 /* abreast DM-scheme for hashing */
- #define error -1 /* error constant */
- #define eol -2 /* end of line */
- #define colon -3 /* character ':' */
- #define maxInterleave 1024 /* maximal interleave factor + 1 */
- #define nofChar ('~' - '!' + 1) /* number of different printable characters */
- #define maxBufLen (dataSize * 1024) /* size of input and output buffer */
-
- UserKeyT(userKey); /* user selected 128 bit key */
- KeyT(key); /* expanded key with 832 bits */
- DataT(state[maxInterleave]); /* state informations for interleaving modes */
- DataT(hashLow); /* lower 64 bits of hash value */
- DataT(hashHigh); /* higher 64 bits of hash value */
-
- u_int32 inputLen = 0; /* current number of bytes read from 'inFile' */
- int interleave = 0; /* current interleave factor */
- int time = 0; /* time for interleaving modes */
- int time_N = 0; /* time-interleave for interleaving modes */
- int mode = nomode; /* current mode */
-
- int optEncrypt = FALSE; /* encrypt option 'e' */
- int optDecrypt = FALSE; /* decrypt option 'd' */
- int optHash = FALSE; /* hash option 'h' */
- int optCopyHash = FALSE; /* copy and hash option 'H' */
- int optKeyHexString = FALSE; /* key as hex-string option 'K' */
- int optKeyString = FALSE; /* key as string option 'k' */
- int optRas = FALSE; /* raster file option 'r' */
- int optTime = FALSE; /* measure time option 'T' */
-
- int inBufLen = maxBufLen; /* current length of data in 'inBuf' */
- int inBufPos = maxBufLen; /* current read position of 'inBuf' */
- int outBufLen = 0; /* current write position of 'outBuf' */
- u_int8 inBuf[maxBufLen]; /* buffer for file read */
- u_int8 outBuf[maxBufLen]; /* buffer for file write */
-
- FILE *inFile; /* file with input data (plain or ciphertext) */
- FILE *outFile; /* file for output data (plain or ciphertext) */
- FILE *hashFile; /* 128 bit hash value is written to this file */
-
- #ifdef rasterAndTime
- int pictureSize; /* stuff related to raster files */
- Pixrect *picPtr;
- colormap_t colormap;
- u_int8 *picture;
- #endif
-
- /******************************************************************************/
- /* initialize global variables */
-
- void Init()
-
- { int i, pos;
-
- for (i = 0; i < userKeyLen; i++) userKey[i] = 0;
- for (pos = 0; pos < maxInterleave; pos++) {
- for (i = 0; i < dataLen; i++) {
- state[pos][i] = 0;
- }
- }
- } /* Init */
-
- /******************************************************************************/
- /* E R R O R - H A N D L I N G */
- /******************************************************************************/
- /* write usage error message and terminate program */
-
- void UsageError(num)
-
- int num;
- {
- #ifdef rasterAndTime
- fprintf(stderr, "(%d)\n\
- Usage: idea [ -e | -d ] [ -r ] [ -ecb | -cbcN | -cfbN | -ofbN ]\n\
- ( -k keyString | -K keyHexString ) \n\
- [ inputFile [ outputFile ] ] \n\
- idea [ -h | -H ] [ -tan | -abr ] \n\
- [ -k keyString | -K keyHexString ] \n\
- [ inputFile [ [ outputFile ] hashvalFile ] ] \n\
- idea -T \n\
- \nExample: idea -Hk \"k e y\" infile | idea -cbc8 -K 123:9a::eF - outfile\n\
- \n", num);
- #else
- fprintf(stderr, "(%d)\n\
- Usage: idea [ -e | -d ] [ -ecb | -cbcN | -cfbN | -ofbN ] \n\
- ( -k keyString | -K keyHexString ) \n\
- [ inputFile [ outputFile ] ] \n\
- idea [ -h | -H ] [ -tan | -abr ] \n\
- [ -k keyString | -K keyHexString ] \n\
- [ inputFile [ [ outputFile ] hashvalFile ] ] \n\
- \nExample: idea -Hk \"k e y\" infile | idea -cbc8 -K 123:9a::eF - outfile\n\
- \n", num);
- #endif
- exit(-1);
- } /* UsageError */
-
- /******************************************************************************/
- /* write error message and terminate program */
-
- void Error(num, str)
-
- int num;
- char *str;
- { fprintf(stderr, "error %d in idea: %s\n", num, str); exit(-1); } /* Error */
-
- /******************************************************************************/
- /* write system error message and terminate program */
-
- void PError(str)
-
- char *str;
- { perror(str); exit(-1); } /* PError */
-
- /******************************************************************************/
- /* D E C R Y P T I O N / E N C R Y P T I O N */
- /******************************************************************************/
- /* read one data-block from 'inFile' */
-
- int GetData(data)
-
- DataT(data);
- { register int i, len;
- register u_int16 h;
- register u_int8 *inPtr;
-
- if (inBufPos >= inBufLen) {
- if (inBufLen != maxBufLen) return 0;
- inBufLen = fread(inBuf, 1, maxBufLen, inFile);
- inBufPos = 0;
- if (inBufLen == 0) return 0;
- if (inBufLen % dataSize != 0)
- for (i = inBufLen; i % dataSize != 0; i++) inBuf[i] = 0;
- }
- inPtr = &inBuf[inBufPos];
- for (i = 0; i < dataLen; i++) {
- h = ((u_int16)(*inPtr++) & 0xFF) << 8;
- data[i] = h | ((u_int16)(*inPtr++) & 0xFF);
- }
- inBufPos += dataSize;
- if (inBufPos <= inBufLen) len = dataSize;
- else len = inBufLen + dataSize - inBufPos;
- inputLen += len;
- return len;
- } /* GetData */
-
- /******************************************************************************/
- /* write one data-block to 'outFile' */
-
- void PutData(data, len)
-
- DataT(data);
- int len;
- { register int i;
- register u_int16 h;
- register u_int8 *outPtr;
-
- outPtr = &outBuf[outBufLen];
- for (i = 0; i < dataLen; i++) {
- h = data[i];
- *(outPtr++) = (h >> 8) & 0xFF;
- *(outPtr++) = h & 0xFF;
- }
- outBufLen += len;
- if (outBufLen >= maxBufLen) {
- fwrite(outBuf, 1, maxBufLen, outFile);
- outBufLen = 0;
- }
- } /* PutData */
-
- /******************************************************************************/
- /* write last block to 'outFile' and close 'outFile' */
-
- void CloseOutput()
-
- { if (outBufLen > 0) {
- fwrite(outBuf, 1, outBufLen, outFile);
- outBufLen = 0;
- }
- close(outFile);
- } /* CloseOutput */
-
- /******************************************************************************/
- /* increment time and time_N */
-
- void IncTime()
- { time = (time + 1) % maxInterleave;
- time_N = (time_N + 1) % maxInterleave;
- } /* IncTime */
-
- /******************************************************************************/
- /* encrypt one data-block */
-
- void EncryptData(data)
-
- DataT(data);
- { int i;
-
- switch (mode) {
- case ecb:
- Idea(data, data, key);
- break;
- case cbc:
- for (i = dataLen - 1; i >= 0; i--) data[i] ^= state[time_N][i];
- Idea(data, data, key);
- for (i = dataLen - 1; i >= 0; i--) state[time][i] = data[i];
- IncTime();
- break;
- case cfb:
- Idea(state[time_N], state[time], key);
- for (i = dataLen - 1; i >= 0; i--) data[i] = state[time][i] ^= data[i];
- IncTime();
- break;
- case ofb:
- Idea(state[time_N], state[time], key);
- for (i = dataLen - 1; i >= 0; i--) data[i] ^= state[time][i];
- IncTime();
- break;
- default: break;
- }
- } /* EncryptData */
-
- /******************************************************************************/
- /* decrypt one data-block */
-
- void DecryptData(data)
-
- DataT(data);
- { int i;
-
- switch (mode) {
- case ecb:
- Idea(data, data, key);
- break;
- case cbc:
- for (i = dataLen - 1; i >= 0; i--) state[time][i] = data[i];
- Idea(data, data, key);
- for (i = dataLen - 1; i >= 0; i--) data[i] ^= state[time_N][i];
- IncTime();
- break;
- case cfb:
- for (i = dataLen - 1; i >= 0; i--) state[time][i] = data[i];
- Idea(state[time_N], data, key);
- for (i = dataLen - 1; i >= 0; i--) data[i] ^= state[time][i];
- IncTime();
- break;
- case ofb:
- Idea(state[time_N], state[time], key);
- for (i = dataLen - 1; i >= 0; i--) data[i] ^= state[time][i];
- IncTime();
- break;
- default: break;
- }
- } /* DecryptData */
-
- /******************************************************************************/
- /* hash one data-block */
-
- void HashData(data)
-
- DataT(data);
- { int i;
- UserKeyT(userKey);
- KeyT(key);
- DataT(w);
-
- for (i = dataLen - 1; i >= 0; i--) {
- userKey[i] = hashLow[i];
- userKey[i + dataLen] = data[i];
- }
- ExpandUserKey(userKey, key);
- Idea(hashHigh, w, key);
- if (mode == abr) {
- for (i = dataLen - 1; i >= 0; i--) {
- userKey[i] = data[i];
- userKey[i + dataLen] = hashHigh[i];
- hashHigh[i] ^= w[i];
- w[i] = ~ hashLow[i];
- }
- }
- else { /* mode == tan */
- for (i = dataLen - 1; i >= 0; i--) {
- hashHigh[i] ^= w[i];
- userKey[i] = data[i];
- userKey[i + dataLen] = w[i];
- w[i] = hashLow[i];
- }
- }
- ExpandUserKey(userKey, key);
- Idea(w, w, key);
- for (i = dataLen - 1; i >= 0; i--) hashLow[i] ^= w[i];
- } /* HashData */
-
- /******************************************************************************/
- /* write value of a 16-bit unsigned integer in hex format to 'hashFile' */
-
- void WriteHex(val)
-
- u_int16 val;
- { char str[8];
- int i;
-
- sprintf(str, "%4X", val);
- for (i = 0; i < 4; i++) if (str[i] == ' ') str[i] = '0';
- fprintf(hashFile, "%s", str);
- } /* WriteHex */
-
- /******************************************************************************/
- /* write the hash value to 'hashFile' */
-
- void WriteHashValue()
-
- { int i;
-
- for (i = 0; i < dataLen; i++) WriteHex(hashHigh[i]);
- for (i = 0; i < dataLen; i++) WriteHex(hashLow[i]);
- } /* WriteHashValue */
-
- /******************************************************************************/
- /* store integer 'value' in 'data' */
-
- void PlainLenToData(value, data)
-
- u_int32 value;
- DataT(data);
- { data[3] = (u_int16)((value << 3) & 0xFFFF);
- data[2] = (u_int16)((value >> 13) & 0xFFFF);
- data[1] = (u_int16)((value >> 29) & 0x0007);
- data[0] = 0;
- } /* PlainLenToData */
-
- /******************************************************************************/
- /* extract integer 'value' from 'data' */
-
- void DataToPlainLen(data, value)
-
- DataT(data);
- u_int32 *value;
- { if ((data[0] != 0) || (data[1] > 7) || ((data[3] & 7) != 0))
- Error(1, "input is not a valid cryptogram");
- *value = ((u_int32)(data[3]) >> 3) & 0x1FFF |
- ((u_int32)(data[2]) << 13) |
- ((u_int32)(data[1]) << 29);
- } /* DataToPlainLen */
-
- /******************************************************************************/
- /* encrypt / decrypt complete data-stream or compute hash value of data-stream*/
-
- void CryptData()
-
- { int t, i;
- u_int32 len;
- DataT(dat[4]);
- DataT(data);
-
- if (optRas) {
- #ifdef rasterAndTime
- if (optEncrypt)
- for (i = 0; i <= (pictureSize - dataSize); i += dataSize)
- EncryptData((u_int16 *)&picture[i]);
- else
- for (i = 0; i <= (pictureSize - dataSize); i += dataSize)
- DecryptData((u_int16 *)&picture[i]);
- #endif
- }
- else if (optEncrypt) { /* encrypt data */
- while ((len = GetData(data)) == dataSize) {
- EncryptData(data);
- PutData(data, dataSize);
- }
- if (len > 0) { EncryptData(data); PutData(data, dataSize); }
- PlainLenToData(inputLen, data);
- EncryptData(data);
- PutData(data, dataSize);
- CloseOutput();
- }
- else if (optDecrypt) { /* decrypt data */
- if ((len = GetData(dat[0])) != dataSize) {
- if (len != 0) Error(2, "input is not a valid cryptogram");
- else Error(3, "there are no data to decrypt");
- }
- DecryptData(dat[0]);
- if ((len = GetData(dat[1])) != dataSize) {
- if (len != 0) Error(4, "input is not a valid cryptogram");
- DataToPlainLen(dat[0], &len);
- if (len != 0) Error(5, "input is not a valid cryptogram");
- }
- else {
- DecryptData(dat[1]);
- t = 2;
- while ((len = GetData(dat[t])) == dataSize) {
- DecryptData(dat[t]);
- PutData(dat[(t + 2) & 3], dataSize);
- t = (t + 1) & 3;
- }
- if (len != 0) Error(6, "input is not a valid cryptogram");
- DataToPlainLen(dat[(t + 3) & 3], &len);
- len += 2 * dataSize;
- if ((inputLen < len) && (len <= inputLen + dataSize)) {
- len -= inputLen;
- PutData(dat[(t + 2) & 3], len);
- }
- else Error(7, "input is not a valid cryptogram");
- }
- CloseOutput();
- }
- else { /* compute hash value */
- for (i = dataLen - 1; i >= 0; i--) {
- hashHigh[i] = userKey[i];
- hashLow[i] = userKey[i + dataLen];
- }
- if (optCopyHash) {
- while ((len = GetData(data)) == dataSize) {
- HashData(data);
- PutData(data, dataSize);
- }
- if (len > 0) { HashData(data); PutData(data, len); }
- PlainLenToData(inputLen, data);
- HashData(data);
- CloseOutput();
- }
- else { /* optHash */
- while ((len = GetData(data)) == dataSize) HashData(data);
- if (len > 0) HashData(data);
- PlainLenToData(inputLen, data);
- HashData(data);
- }
- WriteHashValue();
- }
- } /* CryptData */
-
- /******************************************************************************/
- /* measure the time to encrypt 'nofTestData' data-blocks */
-
- void TimeTest()
-
- {
- #ifdef rasterAndTime
- struct tms startTime, endTime;
- DataT(data);
- int i;
- float size, time;
-
- for (i = 0; i < dataLen; i++) data[i] = 0;
- if (times(&startTime) != 0) PError("(8) times");
- for (i = 0; i < nofTestData; i++) Idea(data, data, key);
- if (times(&endTime) != 0) PError("(9) times");
- size = ((float)nofTestData * 8.0 * (float)(dataSize)) / 1048576.0;
- time = (endTime.tms_utime - startTime.tms_utime) / 60.0;
- fprintf(stderr, "user time needed to encrypt %4.1f MBit of data was %4.1f\
- seconds (%6.3f MBit/sec)\n", size, time, size/time);
- #endif
- } /* TimeTest */
-
- /******************************************************************************/
- /* I N I T I A L I Z A T I O N */
- /******************************************************************************/
- /* set option to TRUE */
-
- void SetOption(option)
-
- int *option;
- { if (*option) UsageError(10);
- *option = TRUE;
- } /* SetOption */
-
- /******************************************************************************/
- /* set encryption / decryption mode */
-
- void SetMode(newMode, str)
-
- int newMode;
- char **str;
- { if (mode != nomode) UsageError(11);
- mode = newMode;
- (*str)++; (*str)++;
- if ((newMode == cbc) || (newMode == cfb) || (newMode == ofb)) {
- if (('0' <= **str) && (**str <= '9')) {
- interleave = 0;
- do {
- interleave = 10 * interleave + (**str - '0');
- if (interleave >= maxInterleave)
- Error(12, "interleave factor is too large");
- (*str)++;
- } while (('0' <= **str) && (**str <= '9'));
- if (interleave == 0) Error(13, "interleave factor is zero");
- }
- else interleave = 1;
- }
- } /* SetMode */
-
- /******************************************************************************/
- /* read options from string 'str' */
-
- void ReadOptions(str, readKeyString, readKeyHexString)
-
- char *str;
- int *readKeyString, *readKeyHexString;
- { char ch;
-
- str++;
- *readKeyString = *readKeyHexString = FALSE;
- while((ch = *(str++)) != 0) {
- switch (ch) {
- case 'a':
- if ((str[0] == 'b') && (str[1] == 'r')) SetMode(abr, &str);
- else UsageError(14);
- break;
- case 'c':
- if ((str[0] == 'b') && (str[1] == 'c')) SetMode(cbc, &str);
- else if ((str[0] == 'f') && (str[1] == 'b')) SetMode(cfb, &str);
- else UsageError(15);
- break;
- case 'd': SetOption(&optDecrypt); break;
- case 'e':
- if ((str[0] == 'c') && (str[1] == 'b')) SetMode(ecb, &str);
- else SetOption(&optEncrypt);
- break;
- case 'h': SetOption(&optHash); break;
- case 'H': SetOption(&optCopyHash); break;
- case 'o':
- if ((str[0] == 'f') && (str[1] == 'b')) SetMode(ofb, &str);
- else UsageError(16);
- break;
- case 'k': SetOption(&optKeyString); *readKeyString = TRUE; break;
- case 'K': SetOption(&optKeyHexString); *readKeyHexString = TRUE; break;
- case 't':
- if ((str[0] == 'a') && (str[1] == 'n')) SetMode(tan, &str);
- else UsageError(17);
- break;
- #ifdef rasterAndTime
- case 'r': SetOption(&optRas); break;
- case 'T': SetOption(&optTime); break;
- #endif
- default: UsageError(18); break;
- }
- }
- if (*readKeyString && *readKeyHexString) UsageError(19);
- } /* ReadOptions */
-
- /******************************************************************************/
- /* check if options are unique and set default options */
-
- void AdjustOptions()
-
- { if (optTime && (optDecrypt || optEncrypt || optHash || optCopyHash ||
- optKeyString || optKeyHexString || optRas)) UsageError(20);
- if (optDecrypt && optEncrypt) UsageError(21);
- if (optHash && optCopyHash) UsageError(22);
- if (optKeyString && optKeyHexString) UsageError(23);
- if (optDecrypt || optEncrypt) {
- if (optHash || optCopyHash) UsageError(24);
- if ((! optKeyString) && (! optKeyHexString)) UsageError(25);
- if (mode == nomode) { mode = cbc; interleave = 1; }
- else if ((mode == tan) || (mode == abr)) UsageError(26);
- }
- else {
- if (optHash || optCopyHash) {
- if (mode == nomode) mode = tan;
- else if ((mode != tan) && (mode != abr)) UsageError(27);
- }
- else {
- if (mode == nomode) { mode = cbc; interleave = 1; }
- if ((mode == tan) || (mode == abr)) SetOption(&optHash);
- else SetOption(&optEncrypt);
- }
- }
- if (optRas && (optHash || optCopyHash)) UsageError(28);
- time = interleave;
- time_N = 0;
- } /* AdjustOptions */
-
- /******************************************************************************/
- /* convert a hex-digit into an integer */
-
- int HexToInt(ch)
-
- char ch;
- {
- if (('0' <= ch) && (ch <= '9')) return ch - '0';
- else if (('a' <= ch) && (ch <= 'f')) return 10 + (ch - 'a');
- else if (('A' <= ch) && (ch <= 'F')) return 10 + (ch - 'A');
- else if (ch == ':') return colon;
- else if (ch == 0) return eol;
- else return error;
- } /* HexToInt */
-
- /******************************************************************************/
- /* convert a character into an integer */
-
- int32 CharToInt(ch)
-
- char ch;
- {
- if (('!' <= ch) && (ch <= '~')) return ch - '!';
- else if (ch == 0) return eol;
- else return error;
- } /* CharToInt */
-
- /******************************************************************************/
- /* initializes key and initial values */
-
- void ReadKeyHexString(str)
-
- char *str;
- { int i, pos;
- int32 h, val;
-
- while ((val = HexToInt(*(str++))) >= 0) {
- for (i = userKeyLen - 1; i >= 0; i--) {
- h = ((int32)(userKey[i]) >> 12) & 0xF;
- userKey[i] = ((int32)(userKey[i]) << 4) | val;
- val = h;
- }
- if (val != 0) Error(29, "key value is too large");
- }
- pos = 0;
- while ((val == colon) && (pos < maxInterleave)) {
- val = HexToInt(*(str++));
- while (val >= 0) {
- for (i = dataLen - 1; i >= 0; i--) {
- h = ((int32)(state[pos][i]) >> 12) & 0xF;
- state[pos][i] = ((int32)(state[pos][i]) << 4) | val;
- val = h;
- }
- if (val != 0) Error(30, "initial value is too large");
- val = HexToInt(*(str++));
- }
- pos++;
- }
- if (val == colon) Error(31, "too many initial values specified");
- if (val != eol) Error(32, "wrong character in initialization string");
- } /* ReadKeyHexString */
-
- /******************************************************************************/
- /* initialize key and initial values */
-
- void ReadKeyString(str)
-
- char *str;
- { int i;
- int32 h, val;
-
- while ((val = CharToInt(*(str++))) >= 0) {
- for (i = userKeyLen - 1; i >= 0; i--) {
- h = (int32)(userKey[i]) * nofChar + val;
- userKey[i] = h & 0xFFFF;
- val = h >> 16;
- }
- }
- } /* ReadKeyString */
-
- /******************************************************************************/
- /* show value of a 16-bit unsigned integer in decimal and hex format */
-
- void ShowInt16(val)
-
- u_int16 val;
- { fprintf(stderr, "%7u<%4x>", val, val);
- } /* ShowInt16 */
-
- /******************************************************************************/
- /* show option name if option is set */
-
- void ShowOption(option, name)
-
- int option;
- char *name;
- { if (option) fprintf(stderr, ", %s", name);
- } /* ShowOption */
-
-
- /******************************************************************************/
- /* show current state informations */
-
- void ShowState()
-
- { int i, j;
-
- fprintf(stderr, "Mode = {");
- switch (mode) {
- case ecb: fprintf(stderr, "ecb"); break;
- case cbc: fprintf(stderr, "cbc"); break;
- case cfb: fprintf(stderr, "cfb"); break;
- case ofb: fprintf(stderr, "ofb"); break;
- case tan: fprintf(stderr, "tan"); break;
- case abr: fprintf(stderr, "abr"); break;
- case nomode: fprintf(stderr, "nomode"); break;
- default: fprintf(stderr, "!!!wrong mode!!!"); break;
- }
- if (interleave > 0) fprintf(stderr, "%d", interleave);
- ShowOption(optEncrypt, "encrypt");
- ShowOption(optDecrypt, "decrypt");
- ShowOption(optHash, "hash");
- ShowOption(optCopyHash, "copy and hash");
- ShowOption(optKeyString, "key string");
- ShowOption(optKeyHexString, "key hex string");
- ShowOption(optRas, "raster file");
- ShowOption(optTime, "time test");
- fprintf(stderr, "}\n\nKey:\n");
- for (i = 0; i < keyLen; i++) {
- ShowInt16(key[i]);
- if ((i % 6) == 5) fprintf(stderr, "\n");
- }
- fprintf(stderr, "\n\nInitial values:");
- for (i = 0; i < interleave; i++) {
- fprintf(stderr, "\n x[N -%2d] =", i + 1);
- for (j = 0; j < dataLen; j++) ShowInt16(state[i][j]);
- }
- fprintf(stderr, "\n");
- } /* ShowState */
-
- /******************************************************************************/
- /* read picture from 'inFile' to memory */
-
- void ReadRasFile()
-
- {
- #ifdef rasterAndTime
- if ((picPtr = pr_load(inFile, &colormap)) == NULL)
- PError("(33) input is not a rasterfile");
- if (picPtr->pr_depth != 8) Error(34, "depth of rasterfile should bee 8");
- picture = (u_int8 *)mpr_d(picPtr)->md_image;
- pictureSize = picPtr->pr_height * picPtr->pr_width;
- #endif
- } /* ReadRasFile */
-
- /******************************************************************************/
- /* write picture from memory to 'outFile' */
-
- void WriteRasFile()
-
- {
- #ifdef rasterAndTime
- if (pr_dump(picPtr, outFile, &colormap, RT_STANDARD, FALSE) != NULL)
- PError("(34) writing rasterfile");
- #endif
- } /* WriteRasFile */
-
- /******************************************************************************/
- /* M A I N - P R O C E D U R E */
- /******************************************************************************/
- main(argc, argv)
-
- int argc;
- char *argv[];
- { int readKeyString, readKeyHexString;
-
- Init();
- argv++; argc--;
- while ((argc > 0) && (*(argv[0]) == '-') && (*(argv[0]+1) != '\0')) {
- ReadOptions(*argv++, &readKeyString, &readKeyHexString); argc--;
- if (readKeyString || readKeyHexString) {
- if (argc <= 0) Error(36, "missing key on command line");
- else if (readKeyString) { ReadKeyString(*(argv++)); argc--; }
- else { ReadKeyHexString(*(argv++)); argc--; }
- }
- }
- AdjustOptions();
- if ((optTime && (argc > 0)) || (optCopyHash && (argc > 3)) ||
- (! optCopyHash && (argc > 2))) Error(37, "too many parameters");
- if (optTime) TimeTest();
- else {
- if ((argc > 1) && (strcmp(argv[0], argv[1]) == 0))
- Error(38, "source and destination are identical");
- if ((argc > 2) && (strcmp(argv[0], argv[2]) == 0))
- Error(39, "source and destination are identical");
- if ((argc > 2) && (strcmp(argv[1], argv[2]) == 0))
- Error(40, "destinations are identical");
- inFile = stdin;
- outFile = hashFile = stdout;
- if (argc > 0) {
- if (strcmp(*argv, "-") == 0) { argv++; argc--; }
- else {
- inFile = fopen(*argv++, "r"); argc--;
- if (inFile == 0) PError(*--argv);
- }
- }
- if (optCopyHash) {
- if (argc > 1) {
- outFile = fopen(*argv++, "w"); argc--;
- if (outFile == 0) PError(*--argv);
- }
- if (argc > 0) {
- hashFile = fopen(*argv++, "w"); argc--;
- if (hashFile == 0) PError(*--argv);
- }
- else hashFile = stderr;
- }
- else if (optHash) {
- if (argc > 0) {
- hashFile = fopen(*argv++, "w"); argc--;
- if (hashFile == 0) PError(*--argv);
- }
- }
- else {
- if (argc > 0) {
- outFile = fopen(*argv++, "w"); argc--;
- if (outFile == 0) PError(*--argv);
- }
- }
- if (argc > 0) Error(41, "too many parameters");
- ExpandUserKey(userKey, key);
- if (optDecrypt && ((mode == ecb) || (mode == cbc))) InvertIdeaKey(key, key);
- /* ShowState(); */
- if (optRas) ReadRasFile();
- CryptData();
- if (optRas) WriteRasFile();
- }
- exit(0);
- }
-